# constructProj/graph.py
# -*-coding:utf-8 -*-
# @file       jsonConfig.py
# @author     yearnext
# @version    1.0.0
# @date       2021-11-19
# @brief      constructProj jsonConfig.py component
import numpy as np
import pyqtgraph as pg
from PyQt5 import QtCore, QtGui, QtWidgets, QtSerialPort
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtSerialPort import *

class baseGraphLineType:
    def __init__(self, initData = []):
        self.data = np.empty(100)
        self.ins  = 0

        for i in range(0, len(initData)):
            self.append(initData[i])

    def append(self, inData):
        self.data[self.ins] = inData
        self.ins += 1

        if self.ins >= self.data.shape[0]:
            tmp = self.data
            self.data = np.empty(tmp.shape[0] * 2)
            self.data[:tmp.shape[0]] = tmp

    def getLen(self):
        return self.ins

    def getGraphData(self):
        return self.data[:self.ins]

    def getData(self, pos):
        if pos >= self.ins:
            return 0

        return self.data[pos]

    def getCurData(self):
        if self.ins == 0:
            return 0

        return self.data[self.ins-1]

    def getCurErr(self):
        if self.ins < 2:
            return 0
        temp1 = self.data[self.ins-1]
        temp2 = self.data[self.ins-2]
        return temp1 - temp2

    def getErrData(self):
        data = baseGraphDataType()

        if self.ins > 1:
            data.append(0)

        for i in range(2, self.ins):
            temp1 = self.data[i]
            temp2 = self.data[i-1]

            data.append(temp2-temp1)

        return data

    def getAvgData(self):
        data = baseGraphDataType()
        temp = baseGraphDataType()

        for i in range(0, self.ins):
            temp.append(self.data[i])
            data.append(temp.getMean())

        return data

    def clearData(self):
        self.data = np.empty(100)
        self.ins  = 0

    def getSum(self):
        x = np.array(self.getGraphData())
        return np.sum(x)

    def getMean(self):
        x = np.array(self.getGraphData())
        return np.mean(x)

    def getMax(self):
        x = np.array(self.getGraphData())
        return np.max(x)

    def getMin(self):
        x = np.array(self.getGraphData())
        return np.min(x)


class baseGraphType(QtCore.QObject):
    sigGraphMouseMoved = QtCore.pyqtSignal(float, float, float)

    def __init__(self, layout, title='图表', enVHLine=0):
        QtCore.QObject.__init__(self)

        self.widget = pg.PlotWidget()  # 实例化一个绘图部件
        self.widget.setTitle(title)
        self.widget.addLegend(size=(100, 50), offset=(0, 0))  # 设置图形的图例
        self.widget.showGrid(x=True, y=True, alpha=0.2)  # 设置图形网格的形式，我们设置显示横线和竖线，并且透明度惟0.5：
        self.widget.setLabel(axis='left', text=u'val')
        self.widget.setLabel(axis='bottom', text=u'time')

        self.widget.setXRange(min=0, max=100, padding=0)
        self.widget.setYRange(min=0, max=100, padding=0)

        self.widget.setDownsampling(mode='peak')
        self.widget.setClipToView(True)
        self.widget.enableAutoRange('xy', 1)
        self.line1 = self.widget.plot(pen='r', name=line1Name)
        self.line2 = self.widget.plot(pen='b', name=line2Name)
        self.layout = layout

        self.curvePoint1 = None
        self.curveText = pg.TextItem(html='<div style="text-align: center"><span style="color: #FFF;"></span></div>',
                                     anchor=(-0.3, 0.5), angle=0, border='w', fill=(0, 0, 255, 100))
        self.arrow1 = pg.ArrowItem(angle=90, pen='r', brush='r')

        self.curvePoint2 = None
        self.arrow2 = pg.ArrowItem(angle=90, pen='b', brush='b')

        self.enVHLine = enVHLine

        if self.enVHLine:
            self.vLine = pg.InfiniteLine(pen=(0, 0, 0), angle=90, movable=False)
            self.hLine = pg.InfiniteLine(pen=(0, 0, 0), angle=0, movable=False)
            self.widget.addItem(self.vLine, ignoreBounds=True)
            self.widget.addItem(self.hLine, ignoreBounds=True)
            self.proxy = pg.SignalProxy(self.widget.scene().sigMouseMoved, rateLimit=60, slot=self.mouseMoved)
        else:
            self.vLine = None
            self.hLine = None
            self.proxy = None

        self.layout.addWidget(self.widget)

    def setTitle(self, title):
        self.widget.setTitle(title)

    # def removeTips(self):

    # def addTips(self):

    def setLines(self, line1Data, line2Data):
        self.line1.setData(line1Data)
        self.line2.setData(line2Data)

        if self.curvePoint1 is not None:
            # self.widget.removeItem(self.curvePoint1)

            # self.curvePoint1.setPos(0)
            self.curvePoint1.setProperty('index', 0)

        if self.curvePoint2 is not None:
            # self.widget.removeItem(self.curvePoint2)

            # self.curvePoint2.setPos(0)
            self.curvePoint2.setProperty('index', 0)

    def setLine1(self, inData):
        self.line1.setData(inData)

        if self.curvePoint1 is not None:
            # self.curvePoint1.setPos(0)
            self.curvePoint1.setProperty('index', 0)

    def setLine2(self, inData):
        self.line2.setData(inData)

        if self.curvePoint2 is not None:
            # self.curvePoint2.setPos(0)
            self.curvePoint2.setProperty('index', 0)

    # def setLine1Str(self, str):
    #     self.line1.

    def clear(self):
        self.line1.setData([])
        self.line2.setData([])

    def showAllCurvePos(self, xPos):
        if self.curvePoint1 is None:
            self.curvePoint1 = pg.CurvePoint(self.line1)
            self.widget.addItem(self.curvePoint1)
            self.arrow1.setParentItem(self.curvePoint1)
            self.curveText.setParentItem(self.curvePoint1)

        if self.curvePoint2 is None:
            self.curvePoint2 = pg.CurvePoint(self.line2)
            self.widget.addItem(self.curvePoint2)
            self.arrow2.setParentItem(self.curvePoint2)

        line1Data = self.line1.getData()
        x = line1Data[0]
        y = line1Data[1]

        line2Data = self.line2.getData()
        x1 = line2Data[0]
        y1 = line2Data[1]

        if (x is None) or (y is None) or (x1 is None) or (y1 is None):
            return

        xLen = len(x)
        yLen = len(y)

        if xPos < xLen and xPos < yLen and xLen > 1:
            t1 = float('%.1f' % (x[xPos] * 0.2))
            yData1 = float('%.1f' % (y[xPos]))
            yData2 = float('%.1f' % (y1[xPos]))

            disp = '时间:%0.1fSec\n原始数据:%0.1fΩ\n滤波数据:%0.1fΩ' % (float('%.1f' % (t1)), yData1, yData2)

            self.curvePoint1.setPos(xPos / (len(x) - 1))
            self.curvePoint2.setPos(xPos / (len(x1) - 1))
            self.curveText.setText(disp)

            self.sigGraphMouseMoved.emit(t1, yData1, yData2)
        else:
            self.curveText.setText('X Pos Error')

    def mouseMoved(self, evt):
        pos = evt[0]  ## using signal proxy turns original arguments into a tuple
        vb = self.widget.getPlotItem().vb
        if self.widget.sceneBoundingRect().contains(pos):
            mousePoint = vb.mapSceneToView(pos)
            index = int(mousePoint.x())

            line1Data = self.line1.getData()
            x = line1Data[0]
            y = line1Data[1]

            line2Data = self.line2.getData()
            x1 = line2Data[0]
            y1 = line2Data[1]

            if (x is None) or (y is None) or (x1 is None) or (y1 is None):
                return

            xLen = len(x)
            yLen = len(y)

            self.vLine.setPos(mousePoint.x())
            self.hLine.setPos(mousePoint.y())

            if index > 0 and index < xLen:
                t1 = float('%.1f' % (x[index] * 0.2))
                yData1 = float('%.1f' % (y[index]))
                yData2 = float('%.1f' % (y1[index]))

                self.sigGraphMouseMoved.emit(t1, yData1, yData2)
                # print('emit %.1f, %.1f, %.1f'%(t1, yData1, yData2))
